#ifndef GLIB_FACE_HY
#define GLIB_FACE_HY


#include "myvector.h"
#include "gDefines.h"
#include "gTriangle.h"
#include "gLib.h"

class CGraphics;

class CTriangle
{
public:
	enum TriangleState
	{
		STATE_UNSETTLED,
		STATE_VISIABLE,
		STATE_INVISIABLE,
	};

public:
	TriangleState m_state;
	CVector3D m_normal;

public:
	inline CTriangle():
	m_state(STATE_UNSETTLED)
	{}

	virtual inline ~CTriangle()
	{}

	inline TriangleState GetState()
	{ return m_state;}

	inline void SetState(TriangleState state)
	{ m_state = state;}

	inline CVector3D& GetNormal()
	{ return m_normal;}

	virtual CVector3D& CalcNormal() = 0;
};

class CTriangleIndex : public CTriangle
{
public:
	int indexA, indexB, indexC;
	gVertex3D *m_vertexBuffer;

public:
	inline CTriangleIndex():
	indexA(0),
	indexB(0),
	indexC(0)
	{}

	inline CTriangleIndex(gVertex3D *vertexBuffer, int *index)
	{
		indexA = index[0];
		indexB = index[1];
		indexC = index[2];
		m_vertexBuffer = vertexBuffer;
	}

	inline ~CTriangleIndex()
	{}

	inline void SetVertex(gVertex3D *vertexBuffer, int *index)
	{
		indexA = index[0];
		indexB = index[1];
		indexC = index[2];
		m_vertexBuffer = vertexBuffer;
	}

	inline CVector3D& CalcNormal() //caculate the normal of the face in world coordinate
	{
		CVector3D v1 = CVector3D(m_vertexBuffer[indexA].m_pos.x - m_vertexBuffer[indexB].m_pos.x,
							 m_vertexBuffer[indexA].m_pos.y - m_vertexBuffer[indexB].m_pos.y,
							 m_vertexBuffer[indexA].m_pos.z - m_vertexBuffer[indexB].m_pos.z);

		CVector3D v2 = CVector3D(m_vertexBuffer[indexB].m_pos.x - m_vertexBuffer[indexC].m_pos.x,
							 m_vertexBuffer[indexB].m_pos.y - m_vertexBuffer[indexC].m_pos.y,
							 m_vertexBuffer[indexB].m_pos.z - m_vertexBuffer[indexC].m_pos.z);
		m_normal = v1 ^ v2;

		return m_normal;
	}
};

class CTriangleVertex : public CTriangle
{
public:
	gVertex3D va, vb, vc;

public:
	inline CTriangleVertex()
	{}

	inline CTriangleVertex(gVertex3D *a, gVertex3D *b, gVertex3D *c)
	{
		va.m_pos.x = a->m_pos.x;
		va.m_pos.y = a->m_pos.y;
		va.m_pos.z = a->m_pos.z;
		va.m_pos.w = a->m_pos.w;

		vb.m_pos.x = b->m_pos.x;
		vb.m_pos.y = b->m_pos.y;
		vb.m_pos.z = b->m_pos.z;
		vb.m_pos.w = b->m_pos.w;

		vc.m_pos.x = c->m_pos.x;
		vc.m_pos.y = c->m_pos.y;
		vc.m_pos.z = c->m_pos.z;
		vc.m_pos.w = c->m_pos.w;
	}

	inline ~CTriangleVertex()
	{}

	inline void SetVertex(gVertex3D *a, gVertex3D *b, gVertex3D *c)
	{
		va.m_pos.x = a->m_pos.x;
		va.m_pos.y = a->m_pos.y;
		va.m_pos.z = a->m_pos.z;
		va.m_pos.w = a->m_pos.w;

		vb.m_pos.x = b->m_pos.x;
		vb.m_pos.y = b->m_pos.y;
		vb.m_pos.z = b->m_pos.z;
		vb.m_pos.w = b->m_pos.w;

		vc.m_pos.x = c->m_pos.x;
		vc.m_pos.y = c->m_pos.y;
		vc.m_pos.z = c->m_pos.z;
		vc.m_pos.w = c->m_pos.w;
	}

	inline CVector3D& CalcNormal() //caculate the normal of the face in world coordinate
	{
		CVector3D v1 = CVector3D(va.m_pos.x - vb.m_pos.x,
							     va.m_pos.y - vb.m_pos.y,
							     va.m_pos.z - vb.m_pos.z);

		CVector3D v2 = CVector3D(vb.m_pos.x - vc.m_pos.x,
							     vb.m_pos.y - vc.m_pos.y,
							     vb.m_pos.z - vc.m_pos.z);
		m_normal = v1 ^ v2;

		return m_normal;
	}
};

#endif